﻿#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_timer = new QTimer;
    m_timer->setInterval(1000);

    this->setWindowTitle("智能加速度测量系统@电子装备结构设计教育部重点实验室");
    //Thread Init
    AxisAdjust* axisAdjust = new AxisAdjust;
    axisAdjust->moveToThread(&axisAdjustThread);
    qRegisterMetaType<QList<qreal>>("QList<qreal>");
    connect(&axisAdjustThread, &QThread::finished, axisAdjust, &QObject::deleteLater);
    connect(this, &MainWindow::ampOperator, axisAdjust, &AxisAdjust::doAdjust);
    connect(axisAdjust, &AxisAdjust::resultReady, this, &MainWindow::handleAmpResults);
    axisAdjustThread.start();
    axisAdjustThread.setPriority(QThread::LowPriority);
    //chart Init
    InitChart();
    labNote = new QLabel;
    labRevCnt = new QLabel;
    labRevCnt->setText("总计接受 0 组数据");
    labRevCnt->setMinimumWidth(200);
    ui->statusBar->addWidget(labRevCnt);
    ui->statusBar->addWidget(labNote);
    /*
     * Bluetooth instance
     *
     * This is an instance of the bluetooth class for
     * communication between the UART friend and this program
     */
    this->bluetooth = new Bluetooth(this);

    connect(bluetooth, SIGNAL(deviceListAvailable()), this, SLOT(refreshDeviceList()));
    connect(bluetooth, SIGNAL(deviceConnected()), this, SLOT(handleBluetoothConnect()));
    connect(bluetooth, SIGNAL(deviceDisconnected()), this, SLOT(handleBluetoothDisconnect()));
    connect(bluetooth, SIGNAL(deviceTransmitReady()), this, SLOT(handleTransmitReady()));

    connect(bluetooth,SIGNAL(dataAvailable()),this,SLOT(readData()));
    connect(m_timer, SIGNAL(timeout()), this, SLOT(receivedDataCount()));

    this->bluetooth->refreshDeviceList();
    /*
     * Timeout Timer
     *
     * This timer is used to timeout device connectinos that take too long
     */
    timeoutTimer = new QTimer(this);
    connect(timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));

//    ui->textShowAccnoG->append(QString::asprintf("%-6.3f", accWithGList[0]));
//    ui->textShowAng->append(QString::asprintf("%-6.3f", accWithGList[0]));

    /*
     * Terminal
     *
     * The terminal is the widget responsible for displaying text and handling
     * data enterred by the user.
     */
//    connect(ui->terminal, SIGNAL(textEnterred(char)), this, SLOT(sendUserInput(char)));

    /*
     *
     * The logger class handles logging data to a file.
     *
     * This class allows logging data as text, hex, splitting log files (TX and RX files), and more.
     */
//    logger = new Logger(this);
//    connect(ui->terminal, SIGNAL(textAdded(QString)), logger, SLOT(log(QString)));

    //Apply default settings here
//    ui->LogPathInput->setText(logger->getLogFilePath());
//    ui->OvevrwritePromptCheck->setChecked(true);
}

MainWindow::~MainWindow()
{
    delete ui;
    axisAdjustThread.quit();
    axisAdjustThread.wait();
}

void MainWindow::startConnectTimeoutTimer()
{
    if(!timeoutTimer){
        timeoutTimer = new QTimer(this);
        connect(timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));
    }
    timeoutTimer->start(5000);
}

void MainWindow::refreshDeviceList()
{
    if(bluetooth){
        QStringList devices = this->bluetooth->getDeviceList();
        ui->BluetoothDevicesBox->clear();
        ui->BluetoothDevicesBox->addItems(devices);
    }
}

void MainWindow::handleBluetoothConnect()
{
    if(bluetooth){
        this->timeoutTimer->stop();
        QString txt = "Connected to " + bluetooth->getDeviceName();
        ui->StatusLabel->setText(txt);
        ui->ConnectButton->setText("断开连接");
        this->state = CONNECTED;
    }
}

void MainWindow::handleBluetoothDisconnect()
{
    if(bluetooth){
        QString txt = "Disconnected from " + bluetooth->getDeviceName();
        ui->StatusLabel->setText(txt);
        ui->ConnectButton->setText("连接");
        this->state = DISCONNECTED;
    }
}

void MainWindow::handleTransmitReady()
{
    if(bluetooth){
        qDebug() << "ready!";
        this->state = READY;
        bluetooth->write("Death and despair!");
    }
}


void MainWindow::sendUserInput(char c)
{
    if(bluetooth){
        bluetooth->write(c);
    }
}

//接收到6个数，分别是AccX最小最大...
void MainWindow::handleAmpResults(const QList<qreal> &ampList)
{
    if(ampList.size() != 6){
        qDebug() << "handleAmpResults() error";
        return;
    }
    axis_X->setRange(ampList[0], ampList[1]);
    axis_X->setRange(ampList[2], ampList[3]);
    axis_X->setRange(ampList[4], ampList[5]);
}

void MainWindow::connectionTimeout()
{
    qDebug() << "Conn timeout";
    this->state = DISCONNECTED;
    ui->StatusLabel->setText("Failed to connect to device");
}

void MainWindow::on_RefreshDevicesButton_released()
{
    if(bluetooth){
        bluetooth->refreshDeviceList();
    }
}

void MainWindow::on_ConnectButton_released()
{
    if(bluetooth){
        if(this->state == DISCONNECTED){
            QString deviceName = ui->BluetoothDevicesBox->currentText();
            if(!deviceName.isEmpty()){
                ui->StatusLabel->setText("Connecting...");
                this->startConnectTimeoutTimer();
                bluetooth->connectToDevice(deviceName);
                m_timer->start();
                RevCnt = 0;
                labRevCnt->setText("总计接受 0 组数据");
            }
        }
        else{       
            bluetooth->disconnectFromDevice();
            m_timer->stop();
        }
    }
}

//void MainWindow::on_EchoTerminalCheck_toggled(bool checked)
//{
//    ui->terminal->enableEcho(checked);
//}

//void MainWindow::on_DisplayInHexCheck_toggled(bool checked)
//{
//    if(checked){
//        ui->terminal->setDisplayMode(Terminal::HEX);
//    }
//    else{
//        ui->terminal->setDisplayMode(Terminal::ASCII);
//    }
//}

//void MainWindow::on_BrowseButton_released()
//{
//    QString path = QFileDialog::getSaveFileName(this, "Log File",
//                                                logger->getLogFilePath(),
//                                                "Text Files (*.txt);;CSV Files (*.csv);;All Files (*.*)");

//    logger->setLogFile(path);
//}

//void MainWindow::on_StartStopLoggingButton_released()
//{
//    if(logger->isLogging()){
//        logger->stopLogging();
//        ui->StartStopLoggingButton->setText("Start Logging");
//    }
//    else{
//        logger->startLogging();
//        if(logger->isLogging()){
//            ui->StartStopLoggingButton->setText("Stop Logging");
//        }
//    }
//}

//void MainWindow::on_LogRawDataCheck_toggled(bool checked)
//{
//    logger->logInHex(checked);
//}

//void MainWindow::on_actionCapture_Terminal_triggered()
//{
//    //Capture the terminal by writing all of the terminal's contents to the logger
//    if(!logger->isLogging()){
//        logger->startLogging();
//        if(logger->isLogging()){
//            logger->log(ui->terminal->getText());
//            logger->stopLogging();
//        }
//    }
//}

//void MainWindow::on_actionStart_Logging_triggered()
//{
//    logger->startLogging();
//}

//void MainWindow::on_actionStop_Logging_triggered()
//{
//    logger->stopLogging();
//}

//void MainWindow::on_OvevrwritePromptCheck_toggled(bool checked)
//{
//    logger->promptWhenOverwriting(checked);
//}

void MainWindow::InitChart()
{
    chartX = new QChart;
    chartY = new QChart;
    chartZ = new QChart;
    seriesX = new QLineSeries;
    seriesY = new QLineSeries;
    seriesZ = new QLineSeries;
    axis_tx = new QValueAxis;
    axis_ty = new QValueAxis;
    axis_tz = new QValueAxis;
    axis_X = new QValueAxis;
    axis_Y = new QValueAxis;
    axis_Z = new QValueAxis;

    //设置字体
    QFont font;
    font.setPixelSize(14);
    font.setBold(1);

    //设置三个图表的X轴
    axis_tx->setRange(0,10);    //  图一X轴范围（0，10）
    axis_tx->setTickCount(10);  //  图一X轴刻度显示10个数字
    axis_ty->setRange(0,10);
    axis_ty->setTickCount(10);
    axis_tz->setRange(0,10);
    axis_tz->setTickCount(10);


    //以加速度单位g来设置Y轴量程  ±1g  （初始图表显示加速度）
    axis_X->setTitleFont(font);
    axis_X->setRange(-1, 1);    //图一Y轴范围
    axis_Y->setTitleFont(font);
    axis_Y->setRange(-1, 1);
    axis_Z->setTitleFont(font);
    axis_Z->setRange(-1, 1);

    axis_X->setTitleText("AccX/g"); //图一Y轴标题
    axis_Y->setTitleText("AccY/g");
    axis_Z->setTitleText("AccZ/g");

    chartX->legend()->hide();
//    chartX->setTitle("AX");
    chartX->addSeries(seriesX);
    chartX->addAxis(axis_tx, Qt::AlignBottom);
    chartX->addAxis(axis_X, Qt::AlignLeft);

    chartY->legend()->hide();
//    chartY->setTitle("AY");
    chartY->addSeries(seriesY);
    chartY->addAxis(axis_ty, Qt::AlignBottom);
    chartY->addAxis(axis_Y, Qt::AlignLeft);

    chartZ->legend()->hide();
//    chartZ->setTitle("AZ");
    chartZ->addSeries(seriesZ);
    chartZ->addAxis(axis_tz, Qt::AlignBottom);
    chartZ->addAxis(axis_Z, Qt::AlignLeft);


    QPen pen(Qt::blue);
    pen.setWidth(2);  
    seriesX->setPen(pen);
    seriesX->append(datat, data[0]);
    seriesX->attachAxis(axis_tx);
    seriesX->attachAxis(axis_X);
    pen.setColor(Qt::red);
    seriesY->setPen(pen);
    seriesY->append(datat, data[1]);
    seriesY->attachAxis(axis_ty);
    seriesY->attachAxis(axis_Y);
    pen.setColor(Qt::green);
    seriesZ->setPen(pen);
    seriesZ->append(datat, data[2]);
    seriesZ->attachAxis(axis_tz);
    seriesZ->attachAxis(axis_Z);

    ui->chartViewX->setChart(chartX);
    ui->chartViewX->setRenderHint(QPainter::Antialiasing);//消锯齿
//    ui->chartViewX->setRubberBand(QChartView::RectangleRubberBand);//启用缩放功能
    ui->chartViewY->setChart(chartY);
    ui->chartViewY->setRenderHint(QPainter::Antialiasing);
//    ui->chartViewY->setRubberBand(QChartView::RectangleRubberBand);
    ui->chartViewZ->setChart(chartZ);
    ui->chartViewZ->setRenderHint(QPainter::Antialiasing);
//    ui->chartViewZ->setRubberBand(QChartView::RectangleRubberBand);

}

void MainWindow::readData()
{
    if(!recFlag) return;
    QList<qreal> dataList;
    dataList = bluetooth->readAll();
    /*0-2有重力加速度的数据
      3-5没有重力加速度的数据
      6-8角度数据*/
    if(dataList.size() == 9){
        accWithGList = dataList.mid(0,3);
        accNoGList = dataList.mid(3,3);
        angList = dataList.mid(6,3);
        RevCnt++;
        labRevCnt->setText(QString::asprintf("总计接收 %d 组数据",RevCnt));
    }
    else{
        labNote->setText("数据读取出错");
        return;
    }
    ui->dataRec->appendPlainText(QString::asprintf("%-15sAccX:  %-6.3fG  AccY:  %-6.3fG  AccZ:  %-6.3fG\r\n"
                                                   "%-15sAccX:  %-6.3fG  AccY:  %-6.3fG  AccZ:  %-6.3fG\r\n"
                                                   "%-15sAccX:  %-6.3f° AccY:  %-6.3f° AccZ:  %-6.3f°\r\n",
                                               "Original Acc", accWithGList[0], accWithGList[1], accWithGList[2],
                                               "After filter", accNoGList[0], accNoGList[1], accNoGList[2],
                                               "Angle", angList[0], angList[1], angList[2]));
    //显示数据
    ui->textShowAccG->clear();
    ui->textShowAccnoG->clear();
    ui->textShowAng->clear();
    ui->textShowAccG->setAlignment(Qt::AlignCenter);
    ui->textShowAccnoG->setAlignment(Qt::AlignCenter);
    ui->textShowAng->setAlignment(Qt::AlignCenter);
    ui->textShowAccG->append("原始加速度/g");
    ui->textShowAccnoG->append("线性加速度/g");
    ui->textShowAng->append("倾角/°");
    ui->textShowAccG->append(QString::asprintf("AccX: %-6.3f", accWithGList[0]));
    ui->textShowAccG->append(QString::asprintf("AccY: %-6.3f", accWithGList[1]));
    ui->textShowAccG->append(QString::asprintf("AccZ: %-6.3f", accWithGList[2]));
    ui->textShowAccnoG->append(QString::asprintf("AccX: %-6.3f", accNoGList[0]));
    ui->textShowAccnoG->append(QString::asprintf("AccY: %-6.3f", accNoGList[1]));
    ui->textShowAccnoG->append(QString::asprintf("AccZ: %-6.3f", accNoGList[2]));
    ui->textShowAng->append(QString::asprintf("X: %-6.3f", angList[0]));
    ui->textShowAng->append(QString::asprintf("Y: %-6.3f", angList[1]));
    ui->textShowAng->append(QString::asprintf("Z: %-6.3f", angList[2]));

    //paint
    int index = ui->comboBoxDataChoice->currentIndex();
    switch(index){
        case 0: data = accNoGList;break;
        case 1: data = accWithGList;break;
        case 2: data = angList;break;
    }
    qreal length = axis_tx->max()-axis_tx->min();
    qreal v = step/length*chartX->plotArea().width();

    datat += step;


    seriesX->append(datat, data[0]);
    seriesY->append(datat, data[1]);
    seriesZ->append(datat, data[2]);


    if(ui->checkBoxShowAll->isChecked() == true){
        axis_tx->setRange(0, datat);
        axis_ty->setRange(0, datat);
        axis_tz->setRange(0, datat);

    }
    else{
        if(datat >= 0.99*length){
            chartX->scroll(v, 0);
            chartY->scroll(v, 0);
            chartZ->scroll(v, 0);
        }
    }
    //准备发送给调整y轴线程的参数
    QList<qreal> operateData(data);
    operateData.push_back((axis_tx->max()-axis_tx->min())/step);
    operateData.push_back(ui->checkBoxShowAll->isChecked() ? 1 : 0);
    //发送数据，5个数，前三个是数据，后面分别是图显数据个数以及是否开启“显示全图”
    emit ampOperator(operateData);
}

void MainWindow::on_btnDataOutput_clicked()
{
    QString textfileName = QFileDialog::getSaveFileName(this, "导出","","*.txt");
    QFile file(textfileName);
    if(!file.open(QFile::WriteOnly|QFile::Text))
    {
        //QMessageBox::information(this,"warning","choose the correct file！");
        return;
    }
    QTextStream out(&file);  //QTextStream会自动将 Unicode 编码同操作系统的编码进行转换
    out << ui->dataRec->toPlainText();
    labNote->setText("数据已导出");
}



void MainWindow::on_btnImageClear_clicked()
{
    ui->dataRec->clear();
    seriesX->clear();
    seriesY->clear();
    seriesZ->clear();
    datat = 0;
    axis_X->setRange(-2, 2);
    axis_Y->setRange(-2, 2);
    axis_Z->setRange(-2, 2);
    axis_tx->setRange(0, 10);
    axis_ty->setRange(0, 10);
    axis_tz->setRange(0, 10);
    labNote->setText("图表/数据接收区清除");
}

void MainWindow::on_btnClearRev_clicked()
{
    ui->dataRec->clear();
    labNote->setText("数据接收区清除");
}

int befCnt = 0;
void MainWindow::receivedDataCount()
{
    labNote->setText(QString::asprintf("每秒接收 %d 组数据", RevCnt-befCnt));
    befCnt = RevCnt;
}

void MainWindow::on_checkBoxShowAll_clicked(bool checked)
{
    if(checked){
        axis_tx->setRange(0, datat);
        axis_X->setRange(minX>0?minX*0.9:minX*1.1, maxX>0?maxX*1.1:maxX*0.9);
        axis_ty->setRange(0, datat);
        axis_Y->setRange(minY>0?minY*0.9:minY*1.1, maxY>0?maxY*1.1:maxY*0.9);
        axis_tz->setRange(0, datat);
        axis_Z->setRange(minZ>0?minZ*0.9:minZ*1.1, maxZ>0?maxZ*1.1:maxZ*0.9);
    }
    else{
        axis_tx->setRange(datat-10, datat);
        axis_ty->setRange(datat-10, datat);
        axis_tz->setRange(datat-10, datat);
    }
}

/*  判断UI(图表内容)                            0 线性加速度       1 原始加速度       2 倾角
        判断UI(Y轴量程)   修改图表Y轴量程 */
void MainWindow::on_comboBoxDataChoice_currentIndexChanged(int index)
{

//清除前边图表显示
//    seriesX->clear();
//    seriesY->clear();
//    seriesZ->clear();

    switch(index)
    {

    //-------线性加速度------->
    case 0:{
                axis_X->setTitleText("AccX/g");
                axis_Y->setTitleText("AccY/g");
                axis_Z->setTitleText("AccZ/g");

                switch(ui->comboBoxAxisRange->currentIndex()){  //判断Y轴量程
                    {
                    //两种加速度之间切换，保证Y轴量程不发生变化
                    case 0:{    axis_X->setRange(-0.1, 0.1);
                                axis_Y->setRange(-0.1, 0.1);
                                axis_Z->setRange(-0.1, 0.1);
                                break;}
                    case 1:{    axis_X->setRange(-0.2, 0.2);
                                axis_Y->setRange(-0.2, 0.2);
                                axis_Z->setRange(-0.2, 0.2);
                                break;}
                    case 2:{    axis_X->setRange(-0.5,0.5);
                                axis_Y->setRange(-0.5,0.5);
                                axis_Z->setRange(-0.5,0.5);
                                break;}
                    case 3:{    axis_X->setRange(-1,1);
                                axis_Y->setRange(-1,1);
                                axis_Z->setRange(-1,1);
                                break;}
                    case 4:{    axis_X->setRange(-2,2);
                                axis_Y->setRange(-2,2);
                                axis_Z->setRange(-2,2);
                                break;}
                    case 5:{    axis_X->setRange(-5,5);
                                axis_Y->setRange(-5,5);
                                axis_Z->setRange(-5,5);
                                break;}

                    //从倾角切换回加速度
                    case 6:{    axis_X->setRange(-1,1);
                                axis_Y->setRange(-1,1);
                                axis_Z->setRange(-1,1);
                                ui->comboBoxAxisRange->setCurrentIndex(3);  //设置UI（Y轴量程）为±1.0g
                                break;}
                    }
                }

                break;}

    //-----原始加速度------->
    case 1:{    axis_X->setTitleText("AccX/g");
                axis_Y->setTitleText("AccY/g");
                axis_Z->setTitleText("AccZ/g");

                switch(ui->comboBoxAxisRange->currentIndex()){
                    {
                    //两种加速度之间切换，保证Y轴量程不发生变化
                    case 0:{    axis_X->setRange(-0.1, 0.1);
                                axis_Y->setRange(-0.1, 0.1);
                                axis_Z->setRange(-0.1, 0.1);
                                break;}
                    case 1:{    axis_X->setRange(-0.2, 0.2);
                                axis_Y->setRange(-0.2, 0.2);
                                axis_Z->setRange(-0.2, 0.2);
                                break;}
                    case 2:{    axis_X->setRange(-0.5,0.5);
                                axis_Y->setRange(-0.5,0.5);
                                axis_Z->setRange(-0.5,0.5);
                                break;}
                    case 3:{    axis_X->setRange(-1,1);
                                axis_Y->setRange(-1,1);
                                axis_Z->setRange(-1,1);
                                break;}
                    case 4:{    axis_X->setRange(-2,2);
                                axis_Y->setRange(-2,2);
                                axis_Z->setRange(-2,2);
                                break;}
                    case 5:{    axis_X->setRange(-5,5);
                                axis_Y->setRange(-5,5);
                                axis_Z->setRange(-5,5);
                                break;}

                    //从倾角切换回加速度
                    case 6:{    axis_X->setRange(-1,1);
                                axis_Y->setRange(-1,1);
                                axis_Z->setRange(-1,1);
                                ui->comboBoxAxisRange->setCurrentIndex(3);
                                break;}
                    }
                }

                break;}

    //-----倾角（从加速度切换回倾角）-------->
    case 2:{    axis_X->setTitleText("X/°");
                axis_Y->setTitleText("Y/°");
                axis_Z->setTitleText("Z/°");
                axis_X->setRange(-180,180);
                axis_Y->setRange(-180,180);
                axis_Z->setRange(-180,180);
                ui->comboBoxAxisRange->setCurrentIndex(6);  //显示倾角，设置UI（Y轴量程）为空（人为设置 index为6）
                break;}
    }
}

//判断UI（Y轴量程）的改变  切换图表显示的Y轴量程
void MainWindow::on_comboBoxAxisRange_currentIndexChanged(int index)
{
    if(!(ui->comboBoxDataChoice->currentIndex()==2)){
        switch(index)
        {
        case 0:{    axis_X->setRange(-0.1, 0.1);
                    axis_Y->setRange(-0.1, 0.1);
                    axis_Z->setRange(-0.1, 0.1);
                    break;}
        case 1:{    axis_X->setRange(-0.2, 0.2);
                    axis_Y->setRange(-0.2, 0.2);
                    axis_Z->setRange(-0.2, 0.2);
                    break;}
        case 2:{    axis_X->setRange(-0.5,0.5);
                    axis_Y->setRange(-0.5,0.5);
                    axis_Z->setRange(-0.5,0.5);
                    break;}
        case 3:{    axis_X->setRange(-1,1);
                    axis_Y->setRange(-1,1);
                    axis_Z->setRange(-1,1);
                    break;}
        case 4:{    axis_X->setRange(-2,2);
                    axis_Y->setRange(-2,2);
                    axis_Z->setRange(-2,2);
                    break;}
        case 5:{    axis_X->setRange(-5,5);
                    axis_Y->setRange(-5,5);
                    axis_Z->setRange(-5,5);
                    break;}
        }
    }
}


void MainWindow::on_btnStop_clicked()
{
    recFlag = !recFlag;
    if(recFlag)
        ui->btnStop->setText("停止接收");
    else{
        ui->btnStop->setText("开始接收");
    }
}






